From: Andrew Cooper Date: Thu, 5 Jun 2014 15:43:26 +0000 (+0200) Subject: x86/hvm: correct hvm_ioreq_server_alloc_rangesets() failure path X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~4896 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=a310f00882dfd4b07baedbab1e102cd4d0a4e867;p=xen.git x86/hvm: correct hvm_ioreq_server_alloc_rangesets() failure path Coverity-ID: 1220092 "Unsigned compare against 0" Coverity-ID: 1220093 "Out-of-bounds read" Both of these are cased by the the while() loop in the fail path, which results in an infinite loop and memory corruption from rangeset_destroy(). Move hvm_ioreq_server_free_rangesets() up and use it for cleanup on the failure path. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant --- diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 4f993f4bd1..1f13329e4b 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -824,6 +824,18 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s, } } +static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s, + bool_t is_default) +{ + unsigned int i; + + if ( is_default ) + return; + + for ( i = 0; i < NR_IO_RANGE_TYPES; i++ ) + rangeset_destroy(s->range[i]); +} + static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s, bool_t is_default) { @@ -861,24 +873,11 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s, return 0; fail: - while ( --i >= 0 ) - rangeset_destroy(s->range[i]); + hvm_ioreq_server_free_rangesets(s, 0); return rc; } -static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s, - bool_t is_default) -{ - unsigned int i; - - if ( is_default ) - return; - - for ( i = 0; i < NR_IO_RANGE_TYPES; i++ ) - rangeset_destroy(s->range[i]); -} - static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s, bool_t is_default) {